import StringIO
from django import template
from django.contrib import messages
from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse
from django.forms import ValidationError
from django.http import HttpResponse
from django.shortcuts import redirect
from django.shortcuts import render_to_response

from lxml import etree
from lxml.etree import Element, SubElement
from sgx.validators import *
from transsys import *
from trsysmodis import *
from ts.config import *
from ts.utils import *
from ts.validators import *
from ts.views import *
from sgx.views import _get_transsys_program_by_name
#import pdb; pdb.set_trace();
# Create your views here.

def home(request):
    return render_to_response('index.html',
                              {},
                              context_instance=template.RequestContext(request))

def exportWorkspace(request):
    print "asd"
    root = Element("TranssysWeb")
    
    ts_programs = request.session["ts_programs"]
    ts_programs_node = SubElement(root, "TranssysPrograms")
    for tp in ts_programs:
        tp_node = SubElement(ts_programs_node, "TranssysProgram")
        ts_code_node = SubElement(tp_node, "TranssysCode")
        ts_code_node.text = str(tp["tp"])
        data_sets_node = SubElement(tp_node, "DataSets")
        if tp.has_key("data_set"):
            for k, v in tp["data_set"].items():
                data_set_node = SubElement(data_sets_node, "DataSet")
                data_set_node.set("name", k)
                for k1,v1 in v.items():
                    fc_node = SubElement(data_set_node, "FactorConcentration")
                    fc_node.set("name", k1)
                    fc_node.text = str(v1)
    sgx_programs = request.session["sgx_programs"]
    sgx_programs_node = SubElement(root, "SimgenexPrograms")
    for sgx in sgx_programs:
        print sgx
        sgx_node = SubElement(sgx_programs_node, "SimgenexProgram")
        sgx_node.set("name", sgx["name"])
        sgx_node.set("description", sgx["desc"])
        sgx_code_node = SubElement(sgx_node, "SimgenexCode")
        sgx_code_node.text = str(sgx["sgx"])
        sgx_target_tp_node = SubElement(sgx_node, "TargetTranssysPrograms")
        for target_tp in sgx["target_tp"]:
            target_tp_node = SubElement(sgx_target_tp_node, "TargetTranssysProgram")
            target_tp_node.text = target_tp.name

        sgx_target_data_node = SubElement(sgx_node, "TargetExpressionData")
        if sgx.has_key("target_expression_data"):
            for name, target_data in sgx["target_expression_data"].items():
                target_data_node = SubElement(sgx_target_data_node, "ExpressionSet")
                target_data_node.set("name", name)
                data = StringIO.StringIO("")
                target_data.write_expression_data(data)
                target_data_node.text = data.getvalue()
    xml = etree.tostring(root, pretty_print=True, xml_declaration=True)
    

    #return render_to_response('xml.html',
    #                            {'xmlcode':xml},
    #                            context_instance=template.RequestContext(request))
    #create response object
    response = HttpResponse(mimetype='text/xml')
    response['Content-Disposition'] = 'attachment; filename=transsysWeb.xml'
    response.write(xml)
    return response

def importWorkspace(request):
    """Import workspace from uploading file"""
    if(request.method == "GET"):
        return render_to_response('importWorkspace.html',
                                  context_instance=template.RequestContext(request))
    elif(request.method== "POST"):
        try:
            xml_file = request.FILES["ws_file"]
            #TODO: Validate xml file by DTD or XML Schema
            #Cleaning the session
            request.session.flush()
            #Import workspace to session
            #Transyss Program
            ts_programs = []
            root = etree.parse(xml_file).getroot()
            ts_programs_node = root.find("TranssysPrograms")
            for tp_node in ts_programs_node.iter("TranssysProgram"):
                ts_program = {}
                
                transsys_code = tp_node.find("TranssysCode").text
                tmp = StringIO.StringIO(transsys_code)
                parser = TranssysProgramParser(tmp)
                try:
                    tp = parser.parse_transsys()
                    ts_program["tp"] = tp
                    print tp.name
                except StandardError, e:
                    print e
                    print transsys_code
                    msg="Unable to compile transsys code"
                    messages.error(request, msg)
                    return render_to_response('importWorkspace.html',
                       context_instance=template.RequestContext(request))
                
                ts_program["data_set"] = {}
                data_sets_node = tp_node.find("DataSets")
                for data_set_node in data_sets_node.iter("DataSet"):
                    data_set_name = data_set_node.get("name")
                    ts_program["data_set"][data_set_name] = {}
                    #fc_list = data_set.find("FactorConcentration")
                    for fc in data_set_node.iter("FactorConcentration"):
                        f_name = fc.get("name")
                        f_concentration = float(fc.text)
                        ts_program["data_set"][data_set_name][f_name] = f_concentration
                print ts_program["data_set"]
                ts_programs.append(ts_program)
            request.session["ts_programs"] = ts_programs
            #Simgenex Program
            sgx_programs = []
            sgx_programs_node = root.find("SimgenexPrograms")
            for sgx_node in sgx_programs_node.iter("SimgenexProgram"):
                sgx_program = {}
                sgx_name = sgx_node.get("name")
                sgx_program["name"] = sgx_name
                sgx_desc = sgx_node.get("description")
                sgx_program["desc"] = sgx_desc
                sgx_code = sgx_node.find("SimgenexCode").text
                tmp = StringIO.StringIO(sgx_code)
                sgx_parser = SimGenexObjectiveFunctionParser(tmp)
                try:
                    sgx = sgx_parser.parse_simgenex()
                    sgx_program["sgx"] = sgx
                except StandardError, e:
                    msg="Unable to compile transsys code"
                    messages.error(request, msg)
                    messages.error(request, str(e))
                    return render_to_response('importWorkspace.html',
                       context_instance=template.RequestContext(request))
                #Target transsys program
                target_tp = []
                sgx_target_tp_node = sgx_node.find("TargetTranssysPrograms")
                for target_tp_node in sgx_target_tp_node.iter("TargetTranssysProgram"):
                    target_tp_name = target_tp_node.text
                    tp = _get_transsys_program_by_name(request, target_tp_name)
                    if tp != None:
                        target_tp.append(tp)
                sgx_program["target_tp"] = target_tp
                #Target expression data
                target_expression_data = {}
                sgx_target_expression_data_node = sgx_node.find("TargetExpressionData")
                for target_expression_node in sgx_target_expression_data_node.iter("ExpressionSet"):
                    target_expression_name = target_expression_node.get("name")
                    data = StringIO.StringIO(target_expression_node.text)
                    expression_set = ExpressionSet()
                    expression_set.read(data)
                    target_expression_data[target_expression_name] = expression_set
                sgx_program["target_expression_data"] = target_expression_data
                sgx_programs.append(sgx_program)
            request.session["sgx_programs"] = sgx_programs
            request.session.modified = True
            #import pdb; pdb.set_trace()
            #xml = etree.tostring(root, pretty_print=True, xml_declaration=True)
            return redirect(reverse('ts.views.home'))
        except ValidationError, e:
            messages.error(request, e.messages[0])
            return render_to_response('transsys/addTranssysProgram.html',
                                  {'ts_programs':request.session['ts_programs']},
                                  context_instance=template.RequestContext(request))
